import {onActivated, onDeactivated, onMounted, onUnmounted, ref, toRaw, watch} from "vue";
import {useRouter} from "vue-router";
import {useStore} from "@/stores";
import {useCurrent} from "@/utils/sop/UseCurrentFunc";

export function useListPage(name: string, cfg: any, cb: any=undefined) {
    const config = ref(cfg);
    const store = useStore();
    const flag = ref(false);

    const refList = ref();
    const refDetail = ref();
    const refBread = ref();
    const router = useRouter();
    const isActivated = ref(false);
    const needRefresh = ref(true);
    const hasInit = ref(false);

    const {updateCurrent} = useCurrent(name);

    const current = () => {
        return refBread.value?.getCurrent() || config.value.rootItem;
    }

    const routeToItem = async (path: string) => {
        await router.push({
            path: path
        });
    }

    const checkRoot = (item: any): boolean => {
        return !item || !item.id;
    }

    const routeItem = async (row: any, tag: string) => {
        const item = row || {id: ''};
        let path;

        config.value.isRoot = checkRoot(item);

        if ('bread' === tag) {
            path = refBread.value?.getRoutePath();
        } else if (!config.value.isRoot) {
            path = refBread.value?.routeToPath(item);
        } else {
            path = refBread.value?.routeToRoot();
        }

        if (isActivated.value) {
            await routeToItem(path);
        }

        if (!config.value.isRoot) {
            await refDetail.value?.handleCurrent();
        } else {
            await refDetail.value?.handleSwitch(tag);
        }
    }

    const triggerPath = async (row: any, path: string) => {
        config.value.isRoot = checkRoot(row);
        await updateCurrent(row, 'bread');
    }

    const currentChanged = async (row: any, tag: string) => {
        if (row) {
            await routeItem(row, tag);
        }
        if (cb) {
            await cb(row, tag);
        }
    }

    const refreshData = () => {
        if (needRefresh.value) {
            needRefresh.value = false;
            refList.value?.refresh();
        }
    }

    const getWatch = () => {
        return cfg.watchRealm ? store.realms : store.platform;
    }

    const getWatchName = (): string => {
        return cfg.watchRealm ? 'realm' : 'platform';
    }

    const updatePlatformUi = async (r: boolean) => {
        config.value.isRoot = true;
        const row: any = config.value?.rootItem;
        config.value.isRoot = true;
        await updateCurrent(row, getWatchName());

        if (r) {
            needRefresh.value = true;
            if (isActivated.value) {
                refreshData();
            }
        }
    }

    const doWatch = () => {
        watch(
            () => store.currents[name],
            async (newVal: any, oldVal: any) => {
                if (newVal) {
                    currentChanged(newVal.item, newVal.tag).then();
                }
            }, {immediate: true}
        );

        watch(
            () => getWatch(),
            async (newVal: any, oldVal: any) => {
                const newRaw = toRaw(newVal);
                const oldRaw = toRaw(oldVal);

                if (oldRaw && newRaw.id !== oldRaw.id) {
                    await updatePlatformUi(true);
                }
            }, {immediate: true}
        );
        if (!cfg.watchRealm) {
            watch(
                () => store.tenant,
                async (newVal: any, oldVal: any) => {
                    const newRaw = toRaw(newVal);
                    const oldRaw = toRaw(oldVal);

                    if (oldRaw && newRaw.id !== oldRaw.id) {
                        await updatePlatformUi(true);
                    }
                }, {immediate: true}
            );
        }
    }

    const initList = () => {
        if (!hasInit.value) {
            hasInit.value = true;
            doWatch();
            updateCurrent(config.value?.rootItem).then();
        }
    }

    onMounted(() => {
        flag.value = true;
        if (!router.currentRoute.value.meta.keepAlive) {
            initList();
            refreshData();
        }
    })

    onActivated(() => {
        isActivated.value = true;
        initList();
        refreshData();
    })

    onDeactivated(() => {
        isActivated.value = false;
    })

    onUnmounted(() => {
    })

    return {
        refList,
        refBread,
        refDetail,
        current,
        triggerPath,
    }
}
